package com.example.tongyao.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.poi.util.Units;
import org.apache.poi.xddf.usermodel.chart.*;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.impl.xb.xmlschema.SpaceAttribute;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

import java.io.*;
import java.math.BigInteger;
import java.util.List;

/**
 * manager-for-isp >>> 【cn.com.testor.util】
 * 主要用于存放封装好的poi方法
 *
 * @author: tongyao
 * @since: 2022-06-21 13:54
 */
@Slf4j
public class PoiUtils {

    /**
     * 设置表格边框属性
     * @param xwpfTable
     * @param borderColor
     * @param borderBold
     * @param borderType
     */
    public static void setBorder(XWPFTable xwpfTable, String borderColor, String borderBold, String borderType){
        BigInteger bigInteger = new BigInteger(borderBold);
        STBorder.Enum lineType = STBorder.Enum.forString(borderType);
        CTBorder border = null;

        CTTblBorders borders = xwpfTable.getCTTbl().getTblPr().addNewTblBorders();
        border = borders.addNewInsideH();
        border.setVal(lineType);
        border.setSz(bigInteger);
        border.setColor(borderColor);

        border = borders.addNewInsideV();
        border.setVal(lineType);
        border.setSz(bigInteger);
        border.setColor(borderColor);

        border = borders.addNewLeft();
        border.setVal(lineType);
        border.setSz(bigInteger);
        border.setColor(borderColor);

        border = borders.addNewRight();
        border.setVal(lineType);
        border.setSz(bigInteger);
        border.setColor(borderColor);

        border = borders.addNewTop();
        border.setVal(lineType);
        border.setSz(bigInteger);
        border.setColor(borderColor);

        border = borders.addNewBottom();
        border.setVal(lineType);
        border.setSz(bigInteger);
        border.setColor(borderColor);
        xwpfTable.createRow();
    }


    /**
     * 创建文档中换行
     * @param document 文档对象
     * @param count 换行次数
     */
    public static void addNewLine(XWPFDocument document, int count){
        for (int i = 0; i < count; i++) {
            document.createParagraph();
        }
    }

    /**
     * 设置页面边距
     * @param document
     * @param left
     * @param right
     * @param top
     * @param bottom
     */
    public static void setPageMargin(XWPFDocument document, long left, long right, long top, long bottom) {
        CTSectPr sectPr = document.getDocument().getBody().addNewSectPr();
        CTPageMar    pageMar = sectPr.addNewPgMar();
        pageMar.setLeft(BigInteger.valueOf(left));
        pageMar.setRight(BigInteger.valueOf(right));
        pageMar.setTop(BigInteger.valueOf(top));
        pageMar.setBottom(BigInteger.valueOf(bottom));
    }

    /**
     * 设置word中表格单元居中
     * @param xwpfTableCellList
     * @param colCount
     */
    public static void setTableCellCenter(List<XWPFTableCell> xwpfTableCellList, int colCount){
        for (int i = 0; i < colCount; i++) {
            xwpfTableCellList.get(i).getCTTc().addNewTcPr().addNewVAlign().setVal(STVerticalJc.CENTER);
            xwpfTableCellList.get(i).getCTTc().getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER);
        }
    }


    /**
     * 创建一个单数据折线图
     * @param document
     * @param title
     * @param xTitle
     * @param yTitle
     * @param xAxisKey
     * @param xAxisValue
     * @throws Exception
     */
    public static void createLineChart(
            XWPFDocument document,
            String title,
            String xTitle,
            String yTitle,
            String[] xAxisKey,
            Integer[] xAxisValue
    ) throws Exception{
        // 创建chart图表对象
        XWPFChart chart = document.createChart(540 * Units.EMU_PER_POINT, 11 * Units.EMU_PER_CENTIMETER);


        // 图表相关设置
        chart.setTitleText(title);
        chart.setTitleOverlay(false);

        // 图例设置
        XDDFChartLegend legend = chart.getOrAddLegend();
        legend.setPosition(LegendPosition.TOP); // 图例位置:上下左右

        // X轴(分类轴)相关设置
        XDDFCategoryAxis xAxis = chart.createCategoryAxis(AxisPosition.BOTTOM); // 创建X轴,并且指定位置
        xAxis.setTitle(xTitle); // x轴标题

        XDDFCategoryDataSource keyDataSource = XDDFDataSourcesFactory.fromArray(xAxisKey); // 设置X轴数据


        // Y轴(值轴)相关设置
        XDDFValueAxis yAxis = chart.createValueAxis(AxisPosition.LEFT); // 创建Y轴,指定位置
        yAxis.setTitle(yTitle); // Y轴标题

        // 设置Y轴数据
        XDDFNumericalDataSource<Integer> valueDataSource = XDDFDataSourcesFactory.fromArray(xAxisValue);

        // 创建折线图对象
        XDDFLineChartData lineChart = (XDDFLineChartData) chart.createData(ChartTypes.LINE, xAxis, yAxis);

        // 加载折线图数据集
        XDDFLineChartData.Series lineSeries = (XDDFLineChartData.Series) lineChart.addSeries(keyDataSource, valueDataSource);
        lineSeries.setTitle(yTitle,null);
        // 线条样式:true平滑曲线,false折线
        lineSeries.setSmooth(true);
        // 标记点大小
        lineSeries.setMarkerSize((short) 6);
        // 标记点样式
        lineSeries.setMarkerStyle(MarkerStyle.CIRCLE);



        // 绘制折线图
        chart.plot(lineChart);
        chart.getCTChart().getPlotArea().getLineChartArray(0).addNewVaryColors().setVal(false);
        //chart.getCTChart().addNewSideWall().addNewSpPr().addNewLn().addNewSolidFill().addNewSrgbClr().setVal();

    }

    public static void createTable(
            XWPFDocument document,
            int ColsCount,
            String borderColor,
            int tableHeadHeight,
            int tableBodyHeight,
            List<String> tableHead,
            List<List<Object>> tableBody
    ){
        XWPFParagraph xwpfParagraph = document.createParagraph();
        XWPFTable xwpfTable = xwpfParagraph.getDocument().createTable(tableBody.size(),ColsCount);

        // 设置边框
        setBorder(xwpfTable,borderColor,"1","single");

        //设置表格水平居中
        xwpfTable.setTableAlignment(TableRowAlign.CENTER);

        //设置表格宽度
        CTTblPr ctTblPr = xwpfTable.getCTTbl().addNewTblPr();
        CTTblWidth ctTblWidth = ctTblPr.addNewTblW();
        ctTblWidth.setW(BigInteger.valueOf(10800));

        // 设置表格中的行高
        XWPFTableRow xwpfTableRow = xwpfTable.getRow(0);
        xwpfTableRow.setHeight(tableHeadHeight);

        // 设置表格头
        List<XWPFTableCell> xwpfTableCellList = xwpfTableRow.getTableCells();
        for (int i = 0; i < tableHead.size(); i++) {
            xwpfTableCellList.get(i).setText(tableHead.get(i).toString());
        }

        // 设置单元格居中
        setTableCellCenter(xwpfTableCellList,ColsCount);

        for (int i = 0; i < tableBody.size(); i++) {

            // 设置表格中的行
            xwpfTableRow = xwpfTable.getRow((i+1));
            xwpfTableRow.setHeight(tableBodyHeight);

            for (int j = 0; j < tableBody.get(i).size(); j++) {
                xwpfTableCellList = xwpfTableRow.getTableCells();
                xwpfTableCellList.get(j).setText(tableBody.get(i).get(j).toString());
            }
            // 设置单元格居中
            setTableCellCenter(xwpfTableCellList,ColsCount);
        }
    }

    public static void createTitle(XWPFDocument document, String text, int fontSize){
        addNewLine(document,1);
        XWPFParagraph title = document.createParagraph();//设置活动标题
        title.setAlignment(ParagraphAlignment.LEFT);
        XWPFRun r1 = title.createRun();
        r1.setFontFamily("宋体");
        r1.setText(text);
        r1.setFontSize(fontSize);
    }


    public static void main(String[] args) throws IOException {
        File is = new File("C:\\Users\\zhang\\Desktop\\巡检报告导出模板.docx");//文件路径
        FileInputStream fis = new FileInputStream(is);
        XWPFDocument docx = new XWPFDocument(fis);//文档对象
        CTP ctp = CTP.Factory.newInstance();
        XWPFParagraph paragraph = new XWPFParagraph(ctp, docx);//段落对象
        ctp.addNewR().addNewT().setStringValue("测试页眉8888888");//设置页眉参数
        ctp.addNewR().addNewT().setSpace(SpaceAttribute.Space.PRESERVE);
        CTSectPr sectPr = docx.getDocument().getBody().isSetSectPr() ? docx.getDocument().getBody().getSectPr() : docx.getDocument().getBody().addNewSectPr();
        XWPFHeaderFooterPolicy policy = new XWPFHeaderFooterPolicy(docx, sectPr);
        XWPFHeader header = policy.createHeader(STHdrFtr.DEFAULT, new XWPFParagraph[] { paragraph });
        header.setXWPFDocument(docx);
        OutputStream os = new FileOutputStream("d:\\Test.docx");
        docx.write(os);//输出到本地
    }
}
